/**
  **************************************************************************
  * @file     main.c
  * @version  v2.0.3
  * @date     2021-12-17
  * @brief    main program
  **************************************************************************
  *                       Copyright notice & Disclaimer
  *
  * The software Board Support Package (BSP) that is made available to
  * download from Artery official website is the copyrighted work of Artery.
  * Artery authorizes customers to use, copy, and distribute the BSP
  * software and its related documentation for the purpose of design and
  * development in conjunction with Artery microcontrollers. Use of the
  * software is governed by this copyright notice and the following disclaimer.
  *
  * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  *
  **************************************************************************
  */

#include "bsp.h"
#include "usb_conf.h"
#include "usb_core.h"
#include "usbh_int.h"
#include "usbh_user.h"
#include "usbh_msc_class.h"
#include "ff.h"
#include "os_obj.h"
#include "framework.h"

/* usb global struct define */
extern otg_core_type otg_core_struct;
extern usbh_msc_type usbh_msc;

static uu08 spdf_demo_req = 0;

void usb_clock48m_select(usb_clk48_s clk_s);
void usb_gpio_config(void);
void usb_low_power_wakeup_config(void);

/*****************************************************************************
* @brief   function
*****************************************************************************/
void spdf_task(char en);
void simp_fat_update_manage(const char *mergefile, uint8_t chk0_or_opt1);

/*****************************************************************************
* @brief   var
*****************************************************************************/
static char opt_file[32];
static char merge_file_opt = 0;

/**
  * @brief  usb_task
  * @param  argument
  * @retval none
  */
void usb_task(void const *argument)
{
	uint32_t work_tm_cnt;
	
	// nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

	/* usb gpio config */
	usb_gpio_config();

#ifdef USB_LOW_POWER_WAKUP
	usb_low_power_wakeup_config();
#endif

	/* enable otgfs clock */
	crm_periph_clock_enable(OTG_CLOCK, TRUE);

	/* select usb 48m clcok source */
	usb_clock48m_select(USB_CLK_HEXT);

	/* enable otgfs irq */
	nvic_irq_enable(OTG_IRQ, 0, 0);

	/* init usb */
	usbh_init(&otg_core_struct,
			  USB_FULL_SPEED_CORE_ID,
			  USB_ID,
			  &uhost_class_handler,
			  &usbh_user_handle);
	while (1)
	{
		usbh_loop_handler(&otg_core_struct.host);
		osDelay(1);
		
		// global_state = 7 dicate user app mode
		if(otg_core_struct.host.global_state)
		{
			work_tm_cnt++;
			if(work_tm_cnt > 50 * OS_TICK_FREQ/10)
			{
				if(otg_core_struct.host.global_state < 7)
				{
					/* init usb */
					usbh_init(&otg_core_struct,
							  USB_FULL_SPEED_CORE_ID,
							  USB_ID,
							  &uhost_class_handler,
							  &usbh_user_handle);
				}
			}
		}
		else
		{
			work_tm_cnt = 0;
		}
		
		// msc ready
		if(usbh_msc.ctrl_state ==  USBH_MSC_STATE_GET_LUN)
		{
			if(spdf_demo_req)
			{
				spdf_demo_req = 0;
				//spdf_task(1);
				
				dbg_puts("spdf opt end" PTCR);
			}
			
			// merge file
			if(1 == merge_file_opt)
			{
				merge_file_opt = 0;
				simp_fat_update_manage(opt_file, 0);
			}
			else if(2 == merge_file_opt)
			{
				merge_file_opt = 0;
				simp_fat_update_manage(opt_file, 1);
			}
			else
			{
				merge_file_opt = 0;
			}
		}
		else
		{
			spdf_demo_req = 0;
			merge_file_opt = 0;
		}
		
	}
}

/*******************************************************************************
 * @brief: spdf req
 * @param cfg
 * @return {*}
 ******************************************************************************/
int spdf_req(int argc, char **argv)
{
	if(usbh_msc.ctrl_state ==  USBH_MSC_STATE_GET_LUN)
	{
		spdf_demo_req = 1;
		dbg_puts("spdf demo start" PTCR);
	}
	else
	{
		dbg_puts("usb is not ready" PTCR);
	}
	
	return 0;
}
DBG_FUN_EXPORT(spdf_req);

/*******************************************************************************
 * @brief: spdf req
 * @param cfg
 * @return {*}
 ******************************************************************************/
int merge_file_req(int argc, char **argv)
{
	if(argc < 3)
	{
		dbg_puts("arg is few" PTCR);
		return -1;
	}
	
	if(usbh_msc.ctrl_state ==  USBH_MSC_STATE_GET_LUN)
	{
		if(argv[2][0] == '0')
			merge_file_opt = 1;
		else
			merge_file_opt = 2;
		
		copy_str(argv[1], opt_file, sizeof(opt_file));
		
		dbg_puts("merge file start" PTCR);
	}
	else
	{
		dbg_puts("usb is not ready" PTCR);
	}
	
	return 0;
}
DBG_FUN_EXPORT(merge_file_req);

